import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository, In } from 'typeorm';
import { DeviceDeviceEntity } from '../entity/device';
import { UserInfoEntity } from '../../user/entity/info';
import { Context } from '@midwayjs/koa';
import { PluginService } from '../../plugin/service/info';
import axios from 'axios';
import { UserInfoService } from '../../user/service/info';

/**
 * 设备信息
 */
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class DeviceDeviceService extends BaseService {
  @InjectEntityModel(DeviceDeviceEntity)
  deviceDeviceEntity: Repository<DeviceDeviceEntity>;

  @InjectEntityModel(UserInfoEntity)
  userInfoEntity: Repository<UserInfoEntity>;

  @Inject()
  ctx: Context;

  @Inject()
  pluginService: PluginService;

  @Inject()
  userInfoService: UserInfoService;

  /**
   * 绑定设备
   */
  async addDevice({ deviceNo, userId }: { deviceNo: string; userId: number }) {
    let _no = '';

    // 如果deviceNo含有乱码
    if (deviceNo.includes('A') || deviceNo.includes('B')) {
      // 使用正则分割数字和字母
      const parts = deviceNo.split(/(?<=\d)(?=[A-Za-z])|(?<=[A-Za-z])(?=\d)/);

      // // 对deviceNo进行解码
      // const decodeNo = decodeURIComponent(deviceNo);

      // // 对decodeNo按照#拆分
      _no = parts[0];
    } else {
      _no = deviceNo;
    }

    // 先查看是否有录入设备
    const deviceInfo = await this.deviceDeviceEntity.findOneBy({
      deviceNo: _no,
    });

    if (!deviceInfo) {
      throw new CoolCommException('设备信息暂未录入，请重新输入！');
    }


    if (deviceInfo.userId) {
      throw new CoolCommException('设备已被绑定，请勿重复绑定！');
    }

    return await this.deviceDeviceEntity.update(
      { deviceNo: _no },
      {
        // deviceNo: deviceNo,
        userId: userId,
      }
    );
  }

  // 后台添加设备
  async add({
    deviceNo,
    userId,
    agentId,
  }: {
    deviceNo: string;
    userId?: number;
    agentId?: number;
  }) {
    return await this.deviceDeviceEntity.insert({
      deviceNo,
      userId,
      agentId,
    });
  }

  async sendMs(params: { deviceNo: string; ms: number }) {
    const { deviceNo, ms } = params;
    const instance = await this.pluginService.getInstance('mqtt');
    const parts = deviceNo?.split(/(?<=\d)(?=[A-Za-z])|(?<=[A-Za-z])(?=\d)/);
    const topicNo = parts?.[0] || deviceNo;
    instance.publish(`Service/${topicNo}`, JSON.stringify({ ms: Number(ms) }));
    return 'ok';
  }

  // 批量新增设备
  async addBatch({
    deviceNos,
    userId,
    agentId,
  }: {
    deviceNos: string[];
    userId?: number;
    agentId?: number;
  }) {
    return await this.deviceDeviceEntity.insert(
      deviceNos.map(deviceNo => ({
        deviceNo,
        userId,
        agentId,
      }))
    );
  }

  // 解除设备绑定  
  async unbindDevice({ deviceNo, userId }: { deviceNo: string; userId: number }) {
    let _no = '';

    // 如果deviceNo含有乱码
    if (deviceNo.includes('A') || deviceNo.includes('B')) {
      // 使用正则分割数字和字母
      const parts = deviceNo.split(/(?<=\d)(?=[A-Za-z])|(?<=[A-Za-z])(?=\d)/);

      // // 对deviceNo进行解码
      // const decodeNo = decodeURIComponent(deviceNo);

      // // 对decodeNo按照#拆分
      _no = parts[0];
    } else {
      _no = deviceNo;
    }

    // 先查看是否有录入设备
    const deviceInfo = await this.deviceDeviceEntity.findOneBy({
      deviceNo: _no,
    });

    if (!deviceInfo) {
      throw new CoolCommException('设备信息暂未录入，请重新输入！');
    }


    // if (deviceInfo.userId) {
    //   throw new CoolCommException('设备已被绑定，请勿重复绑定！');
    // }

    return await this.deviceDeviceEntity.update(
      { deviceNo: _no },
      {
        // deviceNo: deviceNo,
        userId: null,
      }
    );
  }

  // 获取设备二维码
  async getDeviceQrCode(params) {
    // 获取插件实例
    const instance = await this.pluginService.getInstance('wx');

    // 获得公众号实例
    const MiniAppAccount = await instance.MiniApp();

    // 获取公众号的 access token
    const token = await MiniAppAccount.getAccessToken();

    const access_token = await token.getToken();

    // 获取 scene 数组
    const scenes = params.scene || [];

    // 存储结果的数组
    const resultList: any[] = [];

    // 遍历每个 scene 生成二维码
    for (const scene of scenes) {
      const requestData = {
        ...params,
        scene: scene,
      };

      // 调用微信接口生成二维码
      const result = await axios.post(
        'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' +
        access_token,
        requestData,
        {
          responseType: 'arraybuffer',
        }
      );

      // 转换为 base64 格式
      const base64Data = Buffer.from(result.data).toString('base64');
      const imageData = `data:image/png;base64,${base64Data}`;

      resultList.push({
        img: imageData,
        requestData,
        scene,
      });
    }

    return resultList;
  }

  // 获取设备列表
  async getDeviceCount() {


    // 查询用户信息
    const userInfo = await this.userInfoService.person(this.ctx.user.id);




    // // 0: 普通用户, 1: 代理, 2: 商户, 3: 平台

    if (userInfo.role === 1) {
      return {
        // 在线设备数
        deviceOnline: await this.deviceDeviceEntity.countBy({
          agentId: userInfo.id,
          deviceStatus: 1,
        }),
        // 离线
        deviceOffline: await this.deviceDeviceEntity.count({
          where: {
            agentId: userInfo.id,
            deviceStatus: In([0, 2])  // 使用 In 操作符
          },
        }),
      };
    }

    if (userInfo.role === 2) {
      console.log('fffffffffffffffffffffffffffffffffffffffff', userInfo);
      return {
        // 在线设备数
        deviceOnline: await this.deviceDeviceEntity.countBy({
          userId: userInfo.id,
          deviceStatus: 1,
        }),
        // 离线
        deviceOffline: await this.deviceDeviceEntity.count({
          where: {
            userId: userInfo.id,
            deviceStatus: In([0, 2])  // 使用 In 操作符
          },
        }),
      };
    }

    if (userInfo.role === 3) {
      return {
        // 在线设备数
        deviceOnline: await this.deviceDeviceEntity.countBy({
          deviceStatus: 1,
        }),
        // 离线
        deviceOffline: await this.deviceDeviceEntity.countBy({
          deviceStatus: 2,
        }),
      };
    }
  }
}
